Polyfem Examples¶
Some imports for plotting
In [1]:
import plotly.offline as plotly
import plotly.graph_objs as go
#Necessary for the notebook
plotly.init_notebook_mode(connected=True)
and algebra
In [2]:
import numpy as np
Now we import polyfempy
In [3]:
import polyfempy as pf
Plotting utility¶
In [4]:
def plot(vertices, connectivity, function):
x = vertices[:,0]
y = vertices[:,1]
if vertices.shape[1] == 3:
z = vertices[:,2]
else:
z = np.zeros(x.shape, dtype=x.dtype)
if connectivity.shape[1] == 3:
f = connectivity
else:
#Convert a tet-mesh into face based triangles.
f = np.ndarray([len(connectivity)*4, 3], dtype=np.int64)
for i in range(len(connectivity)):
f[i*4+0] = np.array([connectivity[i][1], connectivity[i][0], connectivity[i][2]])
f[i*4+1] = np.array([connectivity[i][0], connectivity[i][1], connectivity[i][3]])
f[i*4+2] = np.array([connectivity[i][1], connectivity[i][2], connectivity[i][3]])
f[i*4+3] = np.array([connectivity[i][2], connectivity[i][0], connectivity[i][3]])
mesh = go.Mesh3d(x=x, y=y, z=z,
i=f[:,0], j=f[:,1], k=f[:,2],
intensity=function, flatshading=function is not None,
colorscale='Viridis',
contour=dict(show=True, color='#fff'),
hoverinfo="all")
layout = go.Layout(scene=go.layout.Scene(aspectmode='data'))
fig = go.Figure(data=[mesh], layout=layout)
plotly.iplot(fig)
Set the mesh path
In [5]:
mesh_path = "plane_hole.obj"
create settings
In [6]:
settings = pf.Settings()
Pick linear $P_1$ elements. If the mesh would be a quad it would be $Q_1$
In [7]:
settings.discr_order = 1
Normalize the mesh to be in [0,1]^2
In [8]:
settings.normalize_mesh = True
Choose Young's modulus and poisson ratio
In [9]:
settings.set_material_params("E", 210000)
settings.set_material_params("nu", 0.3)
We are fine with linear material model
In [10]:
settings.tensor_formulation = pf.TensorFormulations.LinearElasticity
Setup the problem
In [11]:
problem = pf.GenericTensor()
sideset 1 has zero displacement in $x$
In [12]:
problem.add_dirichlet_value(1, [0, 0], [True, False])
sideset 4 has zero displacement in $y$
In [13]:
problem.add_dirichlet_value(4, [0, 0], [False, True])
sideset 3 has a force (Neumann) of [100, 0] applied
In [14]:
problem.add_neumann_value(3, [100, 0])
set the problem
In [15]:
settings.set_problem(problem)
Solve!
In [16]:
solver = pf.Solver()
solver.settings(str(settings))
solver.load_mesh(mesh_path)
solver.solve()
Get the solution
In [17]:
[pts, tets, disp] = solver.get_sampled_solution()
diplace the mesh
In [18]:
vertices = pts + disp
and get the stresses
In [19]:
mises, _ = solver.get_sampled_mises_avg()
finally plot with the above code
In [20]:
plot(vertices, tets, mises)
Torsion¶
In [21]:
mesh_path = "square_beam_h.HYBRID"
settings = pf.Settings()
#It is an hex-mesh so we are using Q1
settings.discr_order = 1
settings.normalize_mesh = False
#Choose Young's modulus and poisson ratio
settings.set_material_params("E", 200)
settings.set_material_params("nu", 0.35)
#Non-linear problem
settings.tensor_formulation = pf.TensorFormulations.NeoHookean
#we want to do 5 steps of incremental loading to avoid ambiguities
settings.nl_solver_rhs_steps = 5
#setup problem with fixed sideset, rotating an number of tours
problem = pf.Torsion()
problem.fixed_boundary = 5
problem.turning_boundary = 6
problem.axis_coordiante = 2
problem.n_turns = 0.5
#coear visualization mesh
settings.vismesh_rel_area = 0.001
settings.set_problem(problem)
#solving!
solver = pf.Solver()
solver.settings(str(settings))
solver.load_mesh(mesh_path)
solver.solve()
#takes ~1 min because it is a complicated non-linear problem!
#get solution and stesses as before
[pts, tets, disp] = solver.get_sampled_solution()
vertices = pts + disp
mises, _ = solver.get_sampled_mises_avg()
#plot the 3d result
plot(vertices, tets, mises)
</div>